package jmars.mobile.rbscluster;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FeatureCorrelation {
	private static String path="E:\\BaiduYunDownload\\afterprocess\\";
	private static int samplingSkip = 1;
	private static String module="yuzhong";
	private static String loadFile=path+module+"\\rbs_cluster.arff";
	private static Map<String,String[]> instances=new HashMap<String,String[]>();
	private static Map<String,double[]> trafficRank = new HashMap<String,double[]>();
	private static List<String> instanceKeyList = new ArrayList<String>();
	
	public static void main(String[] args) throws IOException {
		loadInstances();
		FileWriter resultWriter = new FileWriter(path+module+"\\traffic_shape_spearman_between_"+instanceKeyList.size());
		for(int i=0;i<instanceKeyList.size();i++){
			for(int j=0;j<i;j++){
				resultWriter.write(spearmanRho(trafficRank.get(instanceKeyList.get(i)),trafficRank.get(instanceKeyList.get(j)))+"\r\n");
			}
		}
		resultWriter.close();
		resultWriter = new FileWriter(path+module+"\\traffic_shape_pearson_between_"+instanceKeyList.size());
		for(int i=0;i<instanceKeyList.size();i++){
			for(int j=0;j<i;j++){
				resultWriter.write(pearsonRho(instances.get(instanceKeyList.get(i)),instances.get(instanceKeyList.get(j)))+"\r\n");
			}
		}
		resultWriter.close();
		
		resultWriter = new FileWriter(path+module+"\\feature_correlation_"+instanceKeyList.size()+".txt");
		//1-hourEntropy,26-userEntropy,27-typeEntropy,28-sumTraffic
		resultWriter.write("1-hourEntropy,26-userEntropy,27-typeEntropy,28-sumTraffic\r\n");
		int[] idx={1,26,27,28};
		String[] names={"hourEntropy","userEntropy","typeEntropy","sumTraffic"};
		double[] first=new double[instanceKeyList.size()],second=new double[instanceKeyList.size()];
		for(int i=0;i<idx.length;i++){
			for(int j=0;j<i;j++){
				for(int k=0;k<instanceKeyList.size();k++){
					first[k]=Double.parseDouble(instances.get(instanceKeyList.get(k))[idx[i]]);
					second[k]=Double.parseDouble(instances.get(instanceKeyList.get(k))[idx[j]]);
				}
				resultWriter.write(names[i]+" vs "+names[j]+": "+pearsonRho(first,second)+"\r\n");
			}
		}
		
		resultWriter.close();
	}

	private static void loadInstances(){
		try{
			String row;
			int temp;
			String[] cols;
			String lastTraffic;
			Integer lastIdx;
			File file= new File(loadFile);
			FileInputStream ins = new FileInputStream(file);
			BufferedReader reader = new BufferedReader(new InputStreamReader(ins));
			instances.clear();
			instanceKeyList.clear();
			int count=0;
			while((row=reader.readLine())!=null){
				if(row.startsWith("%")||row.startsWith("@"))continue;
				if(row.trim().equals(""))continue;
				count++;
				if(count%samplingSkip!=0)continue;
				cols=row.split(",");
				instances.put(cols[0],cols);
				instanceKeyList.add(cols[0]);
				int[] order = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
				for(int i=0;i<24;i++){
					for(int j=0;j<23-i;j++){
						if(Double.parseDouble(cols[order[j]])>Double.parseDouble(cols[order[j+1]])){
							temp=order[j];order[j]=order[j+1];order[j+1]=temp;
						}
					}
				}
//				for(int t=0;t<24;t++) System.out.print(cols[t+2]+"  ");
//				System.out.println();
//				for(int t=0;t<24;t++) System.out.print(order[t]+"  ");
//				System.out.println();
//				for(int t=0;t<24;t++) System.out.print(cols[order[t]]+"  ");
//				System.out.println();
				
				double[] rank=new double[24];
				lastTraffic=null;
				lastIdx=null;
				for(int t=0;t<24;t++){
					if(lastTraffic==null){
						lastTraffic=cols[order[t]];
						lastIdx=t;
					}else if(!lastTraffic.equals(cols[order[t]])){
						for(int i=lastIdx;i<t;i++){
							rank[order[i]-2]=(double)(lastIdx+1+t)/2;
						}
						lastTraffic=cols[order[t]];
						lastIdx=t;
					}
					if(t==23){
						for(int i=lastIdx;i<=t;i++){
							rank[order[i]-2]=(double)(lastIdx+2+t)/2;
						}
					}
				}
				trafficRank.put(cols[0], rank);
				
//				for(int t=0;t<24;t++) System.out.print(rank[t]+"  ");
//				System.out.println();System.out.println();
			}
			System.out.println(instances.size());
			ins.close();
		}catch(Exception e){
			e.printStackTrace();
		}
	}


	/*
	 * ρX,Y=cov(X,Y)/(σX*σY)=E[(X-u)(Y-v)]/(σX*σY)
	 * ρ=Σ(Xi-u)(Yi-v)/(Math.sqrt(Σ(Xi-u)^2)*Math.sqrt(Σ(Yi-u)^2))
	 */
	public static Double pearsonRho(double[] first, double[] second){
		double u = 0,v = 0;
		for(int t=0;t<first.length;t++){
			u+=first[t];
			v+=second[t];
		}
		u=u/first.length;
		v=v/first.length;
		double e=0,vx=0,vy=0;
		for(int t=0;t<first.length;t++){
			e+=(first[t]-u)*(second[t]-v);
			vx+=Math.pow((first[t]-u),2);
			vy+=Math.pow((second[t]-v),2);
		}
		return e/(Math.sqrt(vx)*Math.sqrt(vy));
	}
	public static Double pearsonRho(String[] first, String[] second){
		double f[]=new double[24];
		double s[]=new double[24];
		for(int i=0;i<f.length;i++){
			f[i]=Double.parseDouble(first[i+2]);
		}
		for(int i=0;i<s.length;i++){
			s[i]=Double.parseDouble(second[i+2]);
		}
		return pearsonRho(f,s);
	}
	public static double spearmanRho(double[] firstRank,double[] secondRank){
		// or return pearsonRho(firstRank,secondRank);
		double sigmaD2=0D;
		for(int t=0;t<firstRank.length;t++)
			sigmaD2+=Math.pow(firstRank[t]-secondRank[t],2);
		return 1-(6*sigmaD2)/(firstRank.length*(Math.pow(firstRank.length, 2)-1));
	}
	
}
